package com.hzit.auth.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hzit.auth.entity.R;
import com.hzit.auth.entity.SecurityUser;
import com.hzit.auth.entity.User;
import com.hzit.auth.security.TokenManager;
import com.hzit.auth.util.ResponseUtil;
import jdk.nashorn.internal.ir.CallNode;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * 类名：
 * 作者：WF
 * 功能：认证过滤器
 */

public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {
	private AuthenticationManager authenticationManager;
	private TokenManager tokenManager;
	private RedisTemplate redisTemplate;

	public TokenLoginFilter(AuthenticationManager authenticationManager, TokenManager tokenManager, RedisTemplate redisTemplate) {
		this.authenticationManager = authenticationManager;
		this.tokenManager = tokenManager;
		this.redisTemplate = redisTemplate;
		this.setPostOnly(false);
		this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/acl/login","POST"));
	}

	//1. 得到用户名及密码进行认证过程

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
		User user = null;
		try {
			user = new ObjectMapper().readValue(request.getInputStream(), User.class);
			UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword(), new ArrayList<>());
			return authenticationManager.authenticate(usernamePasswordAuthenticationToken);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException();
		}
	}
	//2. 认证成功后的逻辑处理
	@Override
	protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
		//2.1 认证成功后保存数据到redis中
		SecurityUser securityUser = (SecurityUser) authResult.getPrincipal();
		String username = securityUser.getCurrentUserInfo().getUsername();
		String token = tokenManager.createToken(username);
		redisTemplate.opsForValue().set(username,securityUser.getPermissionValueList());
		//2.2 返回给前端一个token
		R r = R.ok().data("token", token);
		ResponseUtil.out(response,r);
//		response.getWriter().println(new ObjectMapper().writeValueAsString(r));
//		response.getWriter().flush();
	}

	@Override
	protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
		ResponseUtil.out(response, R.error());
	}


}
